/* 
 * File:   SocketHandler.h
 * Author: Bram
 *
 * Created on January 9, 2013, 1:36 PM
 */

#ifndef GENERALSOCKET_H
#define	GENERALSOCKET_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>

#include "logger.h"



class GeneralSocket {
private:
    
protected:
    int portNumber;        // Socket port number    
    int socketId;          // Socket file descriptor

    int blocking;          // Blocking flag
    int bindFlag;          // Binding flag

    struct sockaddr_in serverAddr;
    
public:
    GeneralSocket() {}
    GeneralSocket(int portNum);
    GeneralSocket(const GeneralSocket& orig);
    virtual ~GeneralSocket();
    
    void setDebug(int);
    void setReuseAddr(int);
    void setKeepAlive(int);
    void setLingerOnOff(bool);
    void setLingerSeconds(int);
    void setSocketBlocking(int);

    // size of the send and receive buffer
    void setSendBufSize(int);
    void setReceiveBufSize(int);

    // retrieve socket option settings
    int  getDebug();
    int  getReuseAddr();
    int  getKeepAlive();
    int  getSendBufSize();
    int  getReceiveBufSize();
    int  getSocketBlocking() { return blocking; }
    int  getLingerSeconds();
    bool getLingerOnOff();
	
    // returns the socket file descriptor
    int getSocketId() { return socketId; }

    // returns the port number
    int getPortNumber() { return portNumber; }
    
    // show the socket 
    friend ostream& operator<<(ostream&,GeneralSocket&);
    
protected:
    void setSocketId(int socketFd) { socketId = socketFd; }

};

class TcpSocket : public GeneralSocket
{

private:

public:

	TcpSocket() {};
	~TcpSocket() {};

	// Constructor.  Used to create a new TCP socket given a port
	TcpSocket(int portId) : GeneralSocket(portId) { };
        
        // connect to the server, a client call
	bool connectToServer(const string&,hostType);
        
        /*
	   Binds the socket to an address and port number
	   a server call
	*/
	void bindSocket();
        
        // Listens to connecting clients, a server call
	void listenToClient(int numPorts = 5);
        
        /*
	   accepts a connecting client.  The address of the connected client 
	   is stored in the parameter
	   a server call
	*/
	TcpSocket* acceptClient(string&);
        
        /*
	   Sends a message to a connected host. The number of bytes sent is returned
	   can be either server call or client call
	*/
	int sendMessage(const string&);
	/*
	   receive messages and stores the message in a buffer
	*/
	int recieveMessage(string&);

	//send file to connected host
	int sendFile(const string&);
        
        //receive file from connected host
	int receiveFile();



private:

	void detectErrorBind(int*,string&);
	void detectErrorSend(int*,string&);
	void detectErrorRecv(int*,string&);
	void detectErrorConnect(int*,string&);
    void detectErrorAccept(int*,string&);
	void detectErrorListen(int*,string&);

};

#endif	/* GENERALSOCKET_H */

